import { Compiler } from "./Compiler";
import { Observer } from "./Observer";

interface Store {
  [propsName: string]: any;
}

type Options = {
  data: Store;
  el: string | Element;
};

export default class Vue {
  private $options: Options;
  $el: Element;
  private readonly $data: Store;
  constructor(options: Options) {
    this.$options = options;
    this.$data = this.$options.data;
    this.$el =
      typeof options.el === "string"
        ? (document.querySelector(options.el) as Element)
        : options.el;
    this._proxyData(this.$data);
    new Observer(this.$data);
    new Compiler(this);
  }
  private _proxyData(data: Store) {
    Object.keys(data).forEach((key) => {
      Object.defineProperty(this, key, {
        enumerable: true,
        configurable: true,
        get(): any {
          return data[key];
        },
        set(v: any) {
          const value = data[key];
          if (v === value) return;
          data[key] = v;
        },
      });
    });
  }
}
